﻿<AttributeUsage(AttributeTargets.Property, Inherited:=False, AllowMultiple:=True)> _
Public Class StringValidatorAttribute
    Inherits BizBloxValidatorAttribute
    Implements iValidator

    Private m_maxLength As Integer = -1
    Private m_allowWhiteSpace As Boolean = True
    Private m_allowDigits As Boolean = True
    Private m_allowLetters As Boolean = True
    Private m_allowPunctuation As Boolean = True
    Private m_allowedExtraCharsList As String = ""
    Private m_allowSymbols As Boolean = True
    Private m_allowAnyCharacters As Boolean = True
    Private m_inferredAsString As Boolean = False

    Public Sub New(ByVal maxLength As Integer, ByVal allowWhiteSpace As Boolean, _
                   ByVal allowDigits As Boolean, ByVal allowLetters As Boolean, _
                   ByVal allowPunctuation As Boolean, ByVal allowSymbols As Boolean, ByVal allowedExtraCharactersList As String)
        Me.m_allowAnyCharacters = False
        Me.m_allowWhiteSpace = allowWhiteSpace
        Me.m_allowDigits = allowDigits
        Me.m_allowPunctuation = allowPunctuation
        Me.m_allowLetters = allowLetters
        Me.m_allowSymbols = allowSymbols
        Me.m_allowedExtraCharsList = allowedExtraCharactersList
        Me.m_maxLength = maxLength
    End Sub

    Public Sub New(ByVal maxLength As Integer)
        Me.m_allowAnyCharacters = True
        Me.m_maxLength = maxLength
    End Sub


    Public Overrides Sub Validate(ByVal o As Object) Implements iValidator.Validate
        If o Is Nothing Then
            Return
        End If
        If o.GetType().ToString() = "System.String" Then
            Me.ValidateLengthImpl(CType(o, String), Me.m_maxLength)
            If Not Me.m_allowAnyCharacters Then
                Me.ValidateCharactersImpl(CType(o, String), Me.m_allowWhiteSpace, Me.m_allowDigits, Me.m_allowLetters, Me.m_allowPunctuation, Me.m_allowSymbols, Me.m_allowedExtraCharsList)
            End If
        End If
    End Sub


    Private Sub ValidateLengthImpl(ByVal input As String, _
                           ByVal maxLength As Integer)
        'Check maximum length
        If input.Length > Me.m_maxLength Then
            Throw New ArgumentOutOfRangeException(Me.PropertyName, input, "This field is longer than the maximum length of " & Me.m_maxLength & ".")
        End If
    End Sub


    Private Sub ValidateCharactersImpl(ByVal input As String, _
                             ByVal allowWhiteSpace As Boolean, _
                             ByVal allowDigits As Boolean, _
                             ByVal allowLetters As Boolean, _
                             ByVal allowPunctuation As Boolean, _
                             ByVal allowSymbols As Boolean, _
                             ByVal allowedExtraCharsList As String)
        'Check allowed characters
        Dim c As Char
        For i As Integer = 0 To input.Length - 1
            Dim result As Boolean = True
            c = input(i)
            If Char.IsPunctuation(c) Then
                result = allowPunctuation
            ElseIf Char.IsWhiteSpace(c) Then
                result = allowWhiteSpace
            ElseIf Char.IsLetter(c) Then
                result = allowLetters
            ElseIf Char.IsDigit(c) Then
                result = allowDigits
            ElseIf Char.IsSymbol(c) Then
                result = allowSymbols
            End If
            If allowedExtraCharsList.Contains(c) Then
                result = True
            End If
            If result = False Then
                Throw New ArgumentOutOfRangeException(Me.PropertyName, input, "This field does not allow the " & c & "character.")
            End If
        Next
    End Sub

End Class
